home *** CD-ROM | disk | FTP | other *** search
/ Enter 2004 April / enter-2004-04.iso / files / httrack-3.30.exe / {app} / src / htsfilters.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-10-11  |  9.8 KB  |  317 lines

  1. /* ------------------------------------------------------------ */
  2. /*
  3. HTTrack Website Copier, Offline Browser for Windows and Unix
  4. Copyright (C) Xavier Roche and other contributors
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20.  
  21. Important notes:
  22.  
  23. - We hereby ask people using this source NOT to use it in purpose of grabbing
  24. emails addresses, or collecting any other private information on persons.
  25. This would disgrace our work, and spoil the many hours we spent on it.
  26.  
  27.  
  28. Please visit our Website: http://www.httrack.com
  29. */
  30.  
  31.  
  32. /* ------------------------------------------------------------ */
  33. /* File: httrack.c subroutines:                                 */
  34. /*       filters ("regexp")                                     */
  35. /* Author: Xavier Roche                                         */
  36. /* ------------------------------------------------------------ */
  37.  
  38.  
  39. // *.gif                  match all gif files 
  40. // *[file]/*[file].exe    match all exe files with one folder structure
  41. // *[A-Z,a-z,0-9,/,?]     match letters, nums, / and ?
  42. // *[A-Z,a-z,0-9,/,?]
  43.  
  44. // *[>10,<100].gif        match all gif files larger than 10KB and smaller than 100KB
  45. // *[file,>10,<100].gif   FORBIDDEN: you must not mix size test and pattern test
  46.  
  47. #include "htsfilters.h"
  48.  
  49. /* specific definitions */
  50. #include "htsbase.h"
  51. #include "htslib.h"
  52. #include <stdio.h>
  53. #include <stdlib.h>
  54. #include <string.h>
  55. #include <ctype.h>
  56. /* END specific definitions */
  57.  
  58. // α partir d'un tableau de {"+*.toto","-*.zip","+*.tata"} dΘfinit si nom est autorisΘ
  59. // optionnel: taille α contr⌠ller (ou numΘro, etc) en pointeur
  60. //            (en de dΘtection de *size, la taille limite est Θcrite par dessus *size)
  61. // exemple: +-*.gif*[<5] == supprimer GIF si <5KB
  62. int fa_strjoker(char** filters,int nfil,char* nom,LLint* size,int* size_flag,int* depth) {
  63.   int verdict = 0;  // on sait pas
  64.   int i;
  65.   LLint sizelimit=0;
  66.   if (size)
  67.     sizelimit=*size;
  68.   for(i=0;i<nfil;i++) {
  69.     LLint sz;
  70.     if (size)
  71.       sz=*size;
  72.     if (strjoker(nom,filters[i] + 1,&sz,size_flag)) {    // reconnu
  73.       if (size)
  74.       if (sz != *size)
  75.         sizelimit=sz;
  76.       if (filters[i][0]=='+')
  77.         verdict = 1;    // autorisΘ
  78.       else
  79.         verdict = -1;   // interdit
  80.       if (depth)
  81.         *depth=i;
  82.     }
  83.   }
  84.   if (size)
  85.     *size=sizelimit;
  86.   return verdict;
  87. }
  88.  
  89.  
  90. // supercomparateur joker (tm)
  91. // compare a et b (b=avec joker dedans), case insensitive [voir CI]
  92. // renvoi l'adresse de la premiΦre lettre de la chaine
  93. // (cαd *[..]toto.. renvoi adresse de toto dans la chaine)
  94. // accepte les dΘlires du genre www.*.*/ * / * truc*.*
  95. // cet algo est 'un peu' rΘcursif mais ne consomme pas trop de tm
  96. // * = toute lettre
  97. // --?-- : spΘcifique α HTTrack et aux ?
  98. HTS_INLINE char* strjoker(char* chaine,char* joker,LLint* size,int* size_flag) {
  99.   int err=0;
  100.   if (strnotempty(joker)==0) {    // fin de chaine joker
  101.     if (strnotempty(chaine)==0)   // fin aussi pour la chaine: ok
  102.       return chaine;
  103.     else if (chaine[0]=='?')
  104.       return chaine;  // --?-- pour les index.html?Choix=2
  105.     else
  106.       return NULL;    // non trouvΘ
  107.   }
  108.  
  109.   // on va progresser en suivant les 'mots' contenus dans le joker
  110.   // un mot peut Ωtre un * ou bien toute autre sΘquence de lettres
  111.   
  112.   if (strcmp(joker,"*")==0) {  // ok, rien aprΦs
  113.     return chaine;
  114.   }
  115.   
  116.   // 1er cas: jokers * ou jokers multiples *[..]
  117.   if (joker[0]=='*') {  // comparer joker+reste (*toto/..)
  118.     int jmp;    // nombre de caractΦres pour le prochain mot dans joker
  119.     int cut = 0;  // interdire tout caractΦre superflu
  120.     char pass[256];
  121.     char LEFT='[',RIGHT=']';
  122.     int unique=0;
  123.  
  124.     switch(joker[1]) {
  125.       case '[':
  126.         LEFT='[';
  127.         RIGHT=']';
  128.         unique=0;
  129.       break;
  130.       case '(':
  131.         LEFT='(';
  132.         RIGHT=')';
  133.         unique=1;
  134.       break;
  135.     }
  136.  
  137.     if ((joker[1]==LEFT) && (joker[2]!=LEFT)) {  // multijoker (tm)
  138.       int i;
  139.       for(i=0;i<256;i++) pass[i]=0;
  140.  
  141.       // noms rΘservΘs
  142.       if ((strfield(joker+2,"file")) || (strfield(joker+2,"name"))) {
  143.         for(i=0;i<256;i++) pass[i]=1;
  144.         pass[(int) '?'] = 0;
  145.         //pass[(int) ';'] = 0;
  146.         pass[(int) '/'] = 0;
  147.         i=2;
  148.         { int len=(int) strlen(joker);
  149.           while ((joker[i]!=RIGHT) && (joker[i]) && (i<len)) i++; 
  150.         }
  151.       } else if (strfield(joker+2,"path")) {
  152.         for(i=0;i<256;i++) pass[i]=1;
  153.         pass[(int) '?'] = 0;
  154.         //pass[(int) ';'] = 0;
  155.         i=2;
  156.         { int len=(int) strlen(joker);
  157.           while ((joker[i]!=RIGHT) && (joker[i]) && (i<len)) i++;
  158.         }
  159.       } else if (strfield(joker+2,"param")) {
  160.         if (chaine[0]=='?') {  // il y a un paramΦtre juste lα
  161.           for(i=0;i<256;i++) pass[i]=1;
  162.         }  // sinon synonyme de 'rien'
  163.         i=2;
  164.         { int len=(int) strlen(joker);
  165.           while ((joker[i]!=RIGHT) && (joker[i]) && (i<len)) i++;
  166.         }
  167.       } else {
  168.         // dΘcode les directives comme *[A-Z,ΓΩε⌠√,0-9]
  169.         i=2;
  170.         if (joker[i] == RIGHT) {    // *[] signifie "plus rien aprΦs"
  171.           cut = 1;    // caractΦre supplΘmentaire interdit
  172.         } else {
  173.           int len=(int) strlen(joker);
  174.           while ((joker[i]!=RIGHT) && (joker[i]) && (i<len)) {
  175.             if ( (joker[i]=='<') || (joker[i]=='>') ) {  // *[<10]
  176.               int lsize=0;
  177.               int lverdict;
  178.               i++;
  179.               if (sscanf(joker+i,"%d",&lsize) == 1) {
  180.                 if (size) {
  181.                   if (*size>=0) {
  182.                     if (size_flag)
  183.                       *size_flag=1;        /* a jouΘ */
  184.                     if (joker[i-1]=='<')
  185.                       lverdict=(*size<lsize);
  186.                     else
  187.                       lverdict=(*size>lsize);
  188.                     if (!lverdict) {
  189.                       return NULL;        // ne correspond pas
  190.                     } else {
  191.                       *size=lsize;
  192.                       return chaine;  // ok
  193.                     }
  194.                   } else
  195.                     return NULL;          // ne correspond pas
  196.                 } else
  197.                   return NULL;          // ne correspond pas (test impossible)
  198.                 // jump
  199.                 while(isdigit((unsigned char)joker[i])) i++;
  200.               }
  201.             }
  202.             else if (joker[i+1]=='-') {  // 2 car, ex: *[A-Z]
  203.               if ((int) (unsigned char) joker[i+2]>(int) (unsigned char) joker[i]) {
  204.                 int j;
  205.                 for(j=(int) (unsigned char) joker[i];j<=(int) (unsigned char) joker[i+2];j++)
  206.                   pass[j]=1;
  207.                 
  208.               } else err=1;
  209.               i+=3;
  210.             } else {            // 1 car, ex: *[ ]
  211.               pass[(int) (unsigned char) joker[i]]=1;
  212.               i++;
  213.             }
  214.             if ((joker[i]==',') || (joker[i]==';')) i++;
  215.           }
  216.         }
  217.       }
  218.       // α sauter dans joker
  219.       jmp=i;
  220.       if (joker[i]) jmp++; 
  221.       
  222.       //
  223.     } else {  // tout autoriser
  224.       //
  225.       int i;
  226.       for(i=0;i<256;i++) pass[i]=1;    // tout autoriser
  227.       jmp=1;
  228.       if (joker[2]==LEFT) jmp=3;        // permet de recher *<crochet ouvrant>
  229.     }
  230.     
  231.     {
  232.       int i,max;
  233.       char* adr;
  234.  
  235.       // la chaine doit se terminer exactement
  236.       if (cut) {
  237.         if (strnotempty(chaine))
  238.           return NULL;    // perdu
  239.         else
  240.           return chaine;  // ok
  241.       }
  242.  
  243.       // comparaison en boucle, c'est ca qui consomme huhu..
  244.       // le tableau pass[256] indique les caractΦres ASCII autorisΘs
  245.  
  246.       // tester sans le joker (pas ()+ mais ()*)
  247.       if (!unique) {
  248.         if ( (adr=strjoker(chaine,joker+jmp,size,size_flag)) ) {
  249.           return adr;
  250.         }
  251.       }
  252.  
  253.       // tester
  254.       i=0; 
  255.       if (!unique)
  256.         max=strlen(chaine);
  257.       else        /* *(a) only match a (not aaaaa) */
  258.         max=1;
  259.       while(i<(int) max) {
  260.         if (pass[(int) (unsigned char) chaine[i]]) {  // caractΦre autorisΘ
  261.           if ( (adr=strjoker(chaine+i+1,joker+jmp,size,size_flag)) ) {
  262.             return adr;
  263.           }
  264.           i++;
  265.         } else i=max+2;  // sortir
  266.       }
  267.  
  268.       // tester chaεne vide
  269.       if (i!=max+2)  // avant c'est ok
  270.       if ( (adr=strjoker(chaine+max,joker+jmp,size,size_flag)) )
  271.         return adr;
  272.         
  273.       return NULL;  // perdu
  274.     }
  275.  
  276.   } else {  // comparer mot+reste (toto*..)
  277.     if (strnotempty(chaine)) {
  278.       int jmp=0,ok=1;
  279.       
  280.       // comparer dΘbut de joker et dΘbut de chaine
  281.       while((joker[jmp]!='*') && (joker[jmp]) && (ok)) {
  282.         // CI : remplacer streql par une comparaison !=
  283.         if (!streql(chaine[jmp],joker[jmp])) {
  284.           ok=0;  // quitter
  285.         }
  286.         jmp++;
  287.       }
  288.       
  289.       // comparaison ok?
  290.       if (ok) {
  291.         // continuer la comparaison.
  292.         if (strjoker(chaine+jmp,joker+jmp,size,size_flag))
  293.           return chaine;    // retourner 1e lettre
  294.       }
  295.       
  296.     }  // strlen(a)
  297.     return NULL;   
  298.   }  // * ou mot
  299.  
  300.   return NULL;
  301. }
  302.  
  303. // recherche multiple
  304. // exemple: find dans un texte de strcpybuff(*[A-Z,a-z],"*[0-9]"); va rechercher la premiΦre occurence
  305. // d'un strcpy sur une variable ayant un nom en lettres et copiant une chaine de chiffres
  306. // ATTENTION!! Eviter les jokers en dΘbut, o∙ gare au temps machine!
  307. char* strjokerfind(char* chaine,char* joker) {
  308.   char* adr;
  309.   while(*chaine) {
  310.     if ( (adr=strjoker(chaine,joker,NULL,NULL)) ) {  // ok trouvΘ
  311.       return adr;
  312.     }
  313.     chaine++;
  314.   }
  315.   return NULL;
  316. }
  317.